<template>
  <div class="data-cleaning">
    <el-tabs v-model="activeTab">
      <el-tab-pane label="数据清洗" name="cleaning">
        <div class="section">
          <h3>原始数据</h3>
          <el-table :data="rawData" style="width: 100%" size="mini">
            <el-table-column prop="id" label="ID" width="60"/>
            <el-table-column prop="timestamp" label="时间戳"/>
            <el-table-column prop="sensorValue" label="传感器值"/>
            <el-table-column prop="status" label="状态"/>
          </el-table>
        </div>
        <div class="section">
          <h3>归一化配置</h3>
          <el-form :inline="true" size="mini">
            <el-form-item label="原始最小值">
              <el-input-number v-model="normalizeConfig.min" :min="0" :max="normalizeConfig.max-1"/>
            </el-form-item>
            <el-form-item label="原始最大值">
              <el-input-number v-model="normalizeConfig.max" :min="normalizeConfig.min+1" :max="10000"/>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="applyNormalization">应用归一化</el-button>
            </el-form-item>
          </el-form>
        </div>
        <div class="section">
          <h3>清洗后数据（已归一化）</h3>
          <el-table :data="cleanedData" style="width: 100%" size="mini">
            <el-table-column prop="id" label="ID" width="60"/>
            <el-table-column prop="timestamp" label="ISO8601时间"/>
            <el-table-column prop="sensorValue" label="原始值"/>
            <el-table-column prop="normalized" label="归一化值"/>
            <el-table-column prop="status" label="状态"/>
          </el-table>
          <div style="margin-top: 10px;">
            <el-alert
              :title="`清洗后数据准确率：${accuracy}%`"
              type="success"
              show-icon
            />
          </div>
        </div>
      </el-tab-pane>
      <el-tab-pane label="数据校验" name="log">
        <div class="section">
          <h3>清洗日志</h3>
          <el-table :data="cleanLog" style="width: 100%" size="mini">
            <el-table-column prop="action" label="操作"/>
            <el-table-column prop="id" label="数据ID"/>
            <el-table-column prop="reason" label="原因"/>
            <el-table-column label="操作">
              <template slot-scope="scope">
                <el-button
                  v-if="scope.row.action === '删除'"
                  type="text"
                  size="mini"
                  @click="restoreData(scope.row.id)"
                >恢复</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script>
const MOCK_DATA = [
  { id: 1, timestamp: 1718000000000, sensorValue: 23.5, status: '正常' },
  { id: 2, timestamp: '2024-06-10 12:00:00', sensorValue: 9999, status: '异常' }, // 异常值
  { id: 3, timestamp: 1718000000000, sensorValue: 23.5, status: '正常' }, // 重复
  { id: 4, timestamp: '2024/06/10 12:01:00', sensorValue: 18.2, status: '正常' },
  { id: 5, timestamp: 1718000060000, sensorValue: -100, status: '异常' }, // 异常值
  { id: 6, timestamp: '2024-06-10T12:02:00Z', sensorValue: 25.1, status: '正常' },
  { id: 7, timestamp: 1718000120000, sensorValue: 30.0, status: '正常' },
  { id: 8, timestamp: '2024-06-10 12:03:00', sensorValue: 22.0, status: '正常' },
  { id: 9, timestamp: 1718000180000, sensorValue: 23.5, status: '正常' }, // 重复值但不同ID
  { id: 10, timestamp: '2024-06-10 12:04:00', sensorValue: 19.8, status: '正常' }
]

const SENSOR_MIN = 0
const SENSOR_MAX = 100
const STORAGE_KEY = 'data_cleaning_data'
const LOG_KEY = 'data_cleaning_log'
const CONFIG_KEY = 'data_cleaning_config'

export default {
  name: 'DataCleaning',
  data() {
    return {
      activeTab: 'cleaning',
      rawData: [],
      cleanedData: [],
      cleanLog: [],
      normalizeConfig: {
        min: SENSOR_MIN,
        max: SENSOR_MAX
      }
    }
  },
  computed: {
    accuracy() {
      const validCount = this.cleanedData.length
      const total = MOCK_DATA.length
      return ((validCount / total) * 100).toFixed(2)
    }
  },
  methods: {
    loadData() {
      const saved = localStorage.getItem(STORAGE_KEY)
      this.rawData = saved ? JSON.parse(saved) : JSON.parse(JSON.stringify(MOCK_DATA))
      const log = localStorage.getItem(LOG_KEY)
      this.cleanLog = log ? JSON.parse(log) : []
      const config = localStorage.getItem(CONFIG_KEY)
      if (config) {
        Object.assign(this.normalizeConfig, JSON.parse(config))
      }
    },
    saveData() {
      localStorage.setItem(STORAGE_KEY, JSON.stringify(this.rawData))
      localStorage.setItem(LOG_KEY, JSON.stringify(this.cleanLog))
      localStorage.setItem(CONFIG_KEY, JSON.stringify(this.normalizeConfig))
    },
    toISO8601(ts) {
      if (typeof ts === 'number') {
        return new Date(ts).toISOString()
      }
      const d = new Date(ts)
      if (!isNaN(d.getTime())) return d.toISOString()
      return ts
    },
    normalize(val) {
      const min = this.normalizeConfig.min
      const max = this.normalizeConfig.max
      if (typeof val !== 'number' || max === min) return null
      return Math.max(0, Math.min(1, (val - min) / (max - min)))
    },
    cleanAll() {
      let seen = new Set()
      let result = []
      let log = []
      this.rawData.forEach(item => {
        const key = `${item.sensorValue}_${this.toISO8601(item.timestamp)}`
        if (seen.has(key)) {
          log.push({ action: '删除', id: item.id, reason: '重复数据' })
          return
        }
        seen.add(key)
        if (typeof item.sensorValue !== 'number' || item.sensorValue < SENSOR_MIN || item.sensorValue > SENSOR_MAX) {
          log.push({ action: '删除', id: item.id, reason: '异常值' })
          return
        }
        const isoTime = this.toISO8601(item.timestamp)
        const norm = this.normalize(item.sensorValue)
        result.push({
          ...item,
          timestamp: isoTime,
          normalized: norm
        })
      })
      this.cleanedData = result
      this.cleanLog = log
      this.saveData()
    },
    applyNormalization() {
      this.cleanAll()
    },
    restoreData(id) {
      const item = MOCK_DATA.find(d => d.id === id)
      if (item && !this.rawData.some(d => d.id === id)) {
        this.rawData.push(item)
        this.cleanLog = this.cleanLog.filter(l => l.id !== id)
        this.cleanAll()
      }
    }
  },
  created() {
    this.loadData()
    this.cleanAll()
  }
}
</script>

<style scoped>
.data-cleaning {
  padding: 20px;
}
.section {
  margin-bottom: 24px;
}
</style>
